/**
 * Copyright (c) 2006 RiseSoft Co.,Ltd  
 * $Header$
 */
package net.risesoft.risebi.collection.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.risesoft.risebi.collection.commons.constants.SystemConstants;
import net.risesoft.risebi.collection.dao.DataOperationDao;
import net.risesoft.risebi.collection.event.eventobj.DataLogEventObj;
import net.risesoft.risebi.collection.event.eventobj.EventObject;
import net.risesoft.risebi.collection.formula.runtime.Auditor;
import net.risesoft.risebi.collection.groovy.Fault;
import net.risesoft.risebi.collection.model.Catalog;
import net.risesoft.risebi.collection.model.RangeObj;
import net.risesoft.risebi.collection.model.ReportData;
import net.risesoft.risebi.collection.model.ReportInstance;
import net.risesoft.risebi.collection.model.RowObj;
import net.risesoft.risebi.collection.model.Template;
import net.risesoft.risebi.collection.model.TemplateIndication;
import net.risesoft.risebi.collection.model.TemplateRange;
import net.risesoft.risebi.collection.model.User;
import net.risesoft.risebi.collection.service.AuditFaultManager;
import net.risesoft.risebi.collection.service.DataOperationManager;
import net.risesoft.risebi.collection.service.DynaBeanManager;
import net.risesoft.risebi.collection.service.ReportInstanceFileManager;
import net.risesoft.risebi.collection.service.ReportInstanceLevelStatusManager;
import net.risesoft.risebi.collection.service.ReportInstanceManager;
import net.risesoft.risebi.collection.service.ReportInstanceOperationManager;
import net.risesoft.risebi.collection.service.TemplateIndicationManager;
import net.risesoft.risebi.collection.service.TemplateManager;
import net.risesoft.risebi.collection.validator.ValidatorManager;
import net.risesoft.risebi.collection.web.BaseAction;
import net.risesoft.risebi.commons.hibernateextension.HibernateUtil;
import net.risesoft.risebi.commons.util.ContextUtil;
import net.risesoft.risebi.commons.util.GUID;

import org.appfuse.dao.Dao;
import org.appfuse.service.impl.BaseManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

/**
 * 
 * @author <a href="mailto: chenjian@risesoft.net">陈健</a>
 * @author <a href="mailto: dingzhaojun@risesoft.net">丁兆俊</a>
 * @version $Revision$
 * 
 */
@Repository(value = "dataOperationManager")
@SuppressWarnings({ "unchecked", "rawtypes" })
public class DataOperationManagerImpl extends BaseManager implements DataOperationManager {

    private DataOperationDao dataOperationDao;
    private TemplateManager templateManager;
    private ReportInstanceManager reportInstanceManager;
    private ReportInstanceLevelStatusManager reportInstanceLevelStatusManager;
    private ReportInstanceOperationManager reportInstanceOperationManager;
    private ReportInstanceFileManager reportInstanceFileManager;

    private Auditor auditor;
    private ValidatorManager validatorManager;
    private AuditFaultManager auditFaultManager;
    private TemplateIndicationManager templateIndicationManager;
    private DynaBeanManager dynaBeanManager;

    @Autowired
    public void setTemplateIndicationManager(TemplateIndicationManager templateIndicationManager) {
        this.templateIndicationManager = templateIndicationManager;
    }

    @Autowired
    public void setReportInstanceFileManager(ReportInstanceFileManager reportInstanceFileManager) {
        this.reportInstanceFileManager = reportInstanceFileManager;
    }

    @Autowired
    public void setAuditFaultManager(AuditFaultManager auditFaultManager) {
        this.auditFaultManager = auditFaultManager;
    }

    @Autowired
    public void setValidatorManager(ValidatorManager validatorManager) {
        this.validatorManager = validatorManager;
    }

    @Autowired
    public void setAuditor(Auditor auditor) {
        this.auditor = auditor;
    }

    @Autowired
    public void setDataOperationDao(DataOperationDao dataOperationDao) {
        this.dataOperationDao = dataOperationDao;
    }

    @Autowired
    public void setReportInstanceManager(ReportInstanceManager reportInstanceManager) {
        this.reportInstanceManager = reportInstanceManager;
    }

    @Autowired
    public void setTemplateManager(TemplateManager templateManager) {
        this.templateManager = templateManager;
    }

    @Autowired
    public void setDynaBeanManager(DynaBeanManager dynaBeanManager) {
        this.dynaBeanManager = dynaBeanManager;
    }

    @Autowired
    public void setReportInstanceOperationManager(ReportInstanceOperationManager reportInstanceOperationManager) {
        this.reportInstanceOperationManager = reportInstanceOperationManager;
    }

    @Autowired
    public void setReportInstanceLevelStatusManager(ReportInstanceLevelStatusManager reportInstanceLevelStatusManager) {
        this.reportInstanceLevelStatusManager = reportInstanceLevelStatusManager;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.appfuse.service.Manager#getDao()
     */
    public Dao getDao() {
        return dataOperationDao;
    }

    public Map addReportData(String clientJsValidationError, ReportInstance ri, ReportData rd, String templateGuid, User user) throws Exception {
        // 建立map提高速度
        Template t = (Template) templateManager.getObject(Template.class, templateGuid);
        List<TemplateIndication> templateIndicationList = t.getTemplateIndications();

        Map<String, TemplateIndication> templateIndicationMap = new HashMap<String, TemplateIndication>();
        for (int i = 0; i < templateIndicationList.size(); i++) {
            TemplateIndication ti = templateIndicationList.get(i);
            templateIndicationMap.put(ti.getAlias_Name(), ti);
        }

        // 组成列代码
        Map<String, Map<String, String>> rangeColumnCodeMap = new HashMap<String, Map<String, String>>();
        List<TemplateRange> templateRangeList = t.getTemplateRanges();
        Map<String, TemplateRange> templateRangeMap = new HashMap<String, TemplateRange>();
        for (int i = 0; i < templateRangeList.size(); i++) {
            TemplateRange templateRange = templateRangeList.get(i);
            templateRangeMap.put(templateRange.getName(), templateRange);
            Map<String, String> columnCodeMap = new HashMap<String, String>();
            rangeColumnCodeMap.put(templateRange.getName(), columnCodeMap);
            String includedAlias = templateRange.getIncludedAlias();
            String[] includedAliasColl = includedAlias.split(",");            
            for (int j = 0; j < includedAliasColl.length; j++) {
                String aliasName = includedAliasColl[j];
                TemplateIndication templateIndication = templateIndicationMap.get(aliasName);
                String catalogGuid = templateIndication.getRelated_Catalog_GUID();
                if(catalogGuid!=null&&!catalogGuid.equals("")){
                    templateRange.setCatalogCodeColumnCode(templateIndication.getAlias_ColumnCode());
                }
                columnCodeMap.put(templateIndication.getAlias_ColumnCode(), templateIndication.getTableName() + "###" + templateIndication.getColumnName());
            }
        }

        return this.addReportData(clientJsValidationError, ri, rd, templateGuid, templateIndicationList, templateIndicationMap, rangeColumnCodeMap, user, true, true, true, false, false, templateRangeMap, templateRangeList);
    }

    public void addReportData2(String templateGuid) throws Exception {
        long startTime = System.currentTimeMillis();
        
        List<ReportInstance> list_ri = this.find("from ReportInstance t where t.template.guid='" + templateGuid + "'");
        for (ReportInstance ri : list_ri) {
            ReportData rd = this.getReportData(ri, templateGuid);
            
            // 建立map提高速度
            Template t = (Template) templateManager.getObject(Template.class, templateGuid);
            List<TemplateIndication> templateIndicationList = t.getTemplateIndications();

            Map<String, TemplateIndication> templateIndicationMap = new HashMap<String, TemplateIndication>();
            for (int i = 0; i < templateIndicationList.size(); i++) {
                TemplateIndication ti = templateIndicationList.get(i);
                templateIndicationMap.put(ti.getAlias_Name(), ti);
            }

            // 组成列代码
            Map<String, Map<String, String>> rangeColumnCodeMap = new HashMap<String, Map<String, String>>();
            List<TemplateRange> templateRangeList = t.getTemplateRanges();
            Map<String, TemplateRange> templateRangeMap = new HashMap<String, TemplateRange>();
            for (int i = 0; i < templateRangeList.size(); i++) {
                TemplateRange templateRange = templateRangeList.get(i);
                templateRangeMap.put(templateRange.getName(), templateRange);
                Map<String, String> columnCodeMap = new HashMap<String, String>();
                rangeColumnCodeMap.put(templateRange.getName(), columnCodeMap);
                String includedAlias = templateRange.getIncludedAlias();
                String[] includedAliasColl = includedAlias.split(",");
                for (int j = 0; j < includedAliasColl.length; j++) {
                    String aliasName = includedAliasColl[j];
                    TemplateIndication templateIndication = templateIndicationMap.get(aliasName);
                    String catalogGuid = templateIndication.getRelated_Catalog_GUID();
                    if(catalogGuid!=null&&!catalogGuid.equals("")){
                        templateRange.setCatalogCodeColumnCode(templateIndication.getAlias_ColumnCode());
                    }
                    columnCodeMap.put(templateIndication.getAlias_ColumnCode(), templateIndication.getTableName() + "###" + templateIndication.getColumnName());
                }
            }

            // saveRange
            if (!"CA68830FFFFFFFFFC14F229A000004EE".equals(templateGuid)) { // 附表6-2省级集中招标采购的药品目录清单
                if (templateRangeList != null && !templateRangeList.isEmpty()) {
                    Map<String, List<Map<String, String>>> savedMap = new HashMap<String, List<Map<String, String>>>();
                    Map<String, RangeObj> ranges = rd.getRanges();
                    if (ranges == null)
                        return;
                    Iterator<String> rangesIt = ranges.keySet().iterator();

                    while (rangesIt.hasNext()) {
                        String rangeName = rangesIt.next();
                        Map<String, String> columnCodeMap = rangeColumnCodeMap.get(rangeName);
                        
                        RangeObj range = ranges.get(rangeName);
                        Map<String, RowObj> rows = range.getRows();
                        Iterator<String> rowIt = rows.keySet().iterator();

                        String tableName = null;
                        while (rowIt.hasNext()) {
                            String rowCatalogCode = rowIt.next();
                            RowObj row = rows.get(rowCatalogCode);
                            Map<String, String> cols = row.getCols();

                            Map<String, String> innerSavedMap = new HashMap<String, String>();
                            List<Map<String, String>> savedList = null;
                            String columnName = null;

                            Iterator<String> colIt = cols.keySet().iterator();
                            while (colIt.hasNext()) {
                                String columnCode = colIt.next();
                                String tableColumn = columnCodeMap.get(columnCode);
                                if (tableColumn == null) {
                                    innerSavedMap.put(columnCode, cols.get(columnCode));
                                    continue;
                                }

                                String[] tableColumnColl = tableColumn.split("###");
                                tableName = tableColumnColl[0].toLowerCase();
                                columnName = tableColumnColl[1].toLowerCase();

                                savedList = savedMap.get(tableName);
                                if (savedList == null) {
                                    savedList = new ArrayList<Map<String, String>>();
                                    savedMap.put(tableName, savedList);
                                }
                                innerSavedMap.put(columnName, cols.get(columnCode));
                            }                            
                            
                            innerSavedMap.put("tabindex", "100.00");
                            innerSavedMap.put("reportinstance_guid", ri.getGuid());
                            innerSavedMap = HibernateUtil.convertType(tableName, innerSavedMap, SystemConstants.REPORT_DYNAMODEL);
                            savedList.add(innerSavedMap);
                        }
                    }

                    this.saveRangeData(savedMap);
                }
            }
        }
        
        long endTime = System.currentTimeMillis();
        System.out.println("程序运行时间（微秒）："+(endTime-startTime));
    }

    public Map addReportData(String clientJsValidationError, ReportInstance ri, ReportData rd, String templateGuid, List<TemplateIndication> templateIndicationList, Map<String, TemplateIndication> templateIndicationMap, Map<String, Map<String, String>> rangeColumnCodeMap, User user, boolean needValidate, boolean needAudit, boolean needSendMessage, boolean fromImp, boolean needSkip, Map<String, TemplateRange> templateRangeMap, List<TemplateRange> templateRangeList) throws Exception {
        Map returnedMap = new HashMap();

        List<Fault> containedFaults = null;
        // 验证数据格式是否正确
        if (needValidate) {
            containedFaults = this.validatorManager.validate(0, templateGuid, rd);
            if (!containedFaults.isEmpty()) {
                returnedMap.put("containedFaults", containedFaults);
                returnedMap.put("validate", "0");
                return returnedMap;
            }
        }

        Map<String, List<Fault>> containedFaultMap = null;
        // 业务审核
        if (needAudit) {
            boolean hasQiangzhixingFault = false;
            containedFaultMap = auditor.doAudit(templateGuid, ri, rd, user);
            Iterator<String> it = containedFaultMap.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next();
                String[] keyColl = key.split("###");
                if (keyColl[1].equals("1")) {
                    hasQiangzhixingFault = true;
                    break;
                }
            }

            if (hasQiangzhixingFault) {
                containedFaults = new ArrayList<Fault>();
                Iterator<Entry<String, List<Fault>>> entryIt = containedFaultMap.entrySet().iterator();
                while (entryIt.hasNext()) {
                    List<Fault> faultList = entryIt.next().getValue();
                    containedFaults.addAll(faultList);
                }
                returnedMap.put("containedFaults", containedFaults);
                returnedMap.put("audit", "0");
                return returnedMap;
            }
        }

        ReportData beforeReportData = new ReportData();
        ReportData afterReportData = new ReportData();

        // 保存
        this.saveData(clientJsValidationError, ri, rd, templateGuid, containedFaultMap, templateIndicationList, templateIndicationMap, rangeColumnCodeMap, user, fromImp, needSkip, templateRangeMap, templateRangeList, beforeReportData, afterReportData);

        // 没有强制性审核错误，只有一般性审核错误，保存非强制性审核错误
        if (needSendMessage) {
            if (!containedFaultMap.isEmpty()) {
                containedFaults = new ArrayList<Fault>();

                for (Map.Entry<String, List<Fault>> entry : containedFaultMap.entrySet()) {
                    String key = entry.getKey();
                    String[] keyColl = key.split("###");
                    if (keyColl[1].equals("1"))
                        continue;

                    List<Fault> faultList = entry.getValue();
                    containedFaults.addAll(faultList);
                }

                auditFaultManager.saveAuditFault(ri.getGuid(), containedFaults);
            }
        }

        // 发送新增、修改数据日志（异步事件）
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("targetGuid", ri.getGuid());
        dataMap.put("beforeReportData", beforeReportData);
        dataMap.put("afterReportData", afterReportData);
        dataMap.put("user", user);
        dataMap.put("baseInfo", false);
        EventObject dataLogEventObject = new DataLogEventObj(this);
        dataLogEventObject.setDataMap(dataMap);
        ContextUtil.getAc().publishEvent(dataLogEventObject);

        returnedMap.put("returnString", BaseAction.ADD);

        return returnedMap;
    }

    public Map validateReportData(int number, User user, ReportInstance ri, ReportData rd, boolean needValidate, boolean needAudit) throws Exception {
        Map returnedMap = new HashMap();

        List<Fault> containedFaults = null;
        // 验证数据格式是否正确
        if (needValidate) {
            containedFaults = this.validatorManager.validate(number, ri.getTemplateGuid(), rd);
            if (!containedFaults.isEmpty()) {
                returnedMap.put("containedFaults", containedFaults);
                returnedMap.put("validate", "0");
                return returnedMap;
            }
        }

        Map<String, List<Fault>> containedFaultMap = null;
        // 业务审核
        if (needAudit) {
            boolean hasQiangzhixingFault = false;
            containedFaultMap = auditor.doAudit(ri.getTemplateGuid(), ri, rd, user);
            Iterator<String> it = containedFaultMap.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next();
                String[] keyColl = key.split("###");
                if (keyColl[1].equals("1")) {
                    hasQiangzhixingFault = true;
                    break;
                }
            }

            if (hasQiangzhixingFault) {
                containedFaults = new ArrayList<Fault>();
                Iterator<Entry<String, List<Fault>>> entryIt = containedFaultMap.entrySet().iterator();
                while (entryIt.hasNext()) {
                    List<Fault> faultList = entryIt.next().getValue();
                    containedFaults.addAll(faultList);
                }
                returnedMap.put("containedFaults", containedFaults);
                returnedMap.put("audit", "0");
                return returnedMap;
            }
        }

        return returnedMap;
    }

    @Transactional(rollbackFor = { java.lang.Exception.class })
    private void saveData(String clientJsValidationError, ReportInstance ri, ReportData rd, String templateGuid, Map<String, List<Fault>> containedFaultMap, List<TemplateIndication> templateIndicationList, Map<String, TemplateIndication> templateIndicationMap, Map<String, Map<String, String>> rangeColumnCodeMap, User user, boolean fromImp, boolean needSkip, Map<String, TemplateRange> templateRangeMap, List<TemplateRange> templateRangeList, ReportData beforeReportData, ReportData afterReportData) throws Exception {
        // 保存游离项
        this.saveIndication(ri, rd, templateGuid, templateIndicationList, templateIndicationMap, fromImp, needSkip, beforeReportData, afterReportData);

        // saveRange
        if ("CA68830FFFFFFFFFC14F229A000004EE".equals(templateGuid)) { // 附表6-2省级集中招标采购的药品目录清单
            // List<ReportInstanceFile> list =
            // reportInstanceFileManager.find("from ReportInstanceFile t where t.reportInstance.guid='"
            // + ri.getGuid() + "'");
            // if(list.size()>0){
            // ReportInstanceFile reportInstanceFile = list.get(0);
            // String name = reportInstanceFile.getName();
            // if(name.endsWith(".xls")){
            // String templateFilePath =
            // FilePersistLocator.getFilePersistLocator("templateFile");
            // File dir = new File(templateFilePath);
            // if(!dir.exists()){
            // dir.mkdirs();
            // }
            //
            // //TemplateRange templateRange = templateRangeList.get(0);
            // String tableName = "dyna_dataset_sjjzzbcg_range";
            //
            // byte[] content = reportInstanceFile.getContent();
            // String filePath = templateFilePath + new GUID().toString(32) +
            // ".xls";
            // File file = new File(filePath);
            // FileOutputStream fos = new FileOutputStream(file);
            // fos.write(content);
            // fos.close();
            //
            // int count = 0;
            // String message = "";
            // try{
            // dynaBeanManager.execute("delete from " + tableName +
            // " t where t.reportinstance_guid='" + ri.getGuid() + "'");
            //
            // HashMap mapFields = new HashMap();
            // mapFields.put("1", "daima");
            // mapFields.put("2", "field1");
            // mapFields.put("3", "field2");
            // mapFields.put("4", "field3");
            // mapFields.put("5", "field4");
            // mapFields.put("6", "field5");
            //
            // String sUnique = "1"; //excel代表catalog的列号
            // int unique = Integer.valueOf(sUnique);
            // String uniqueFieldName = (String) mapFields.get(sUnique);
            // String uniqueFieldvalue = "";
            //
            // Workbook workBook = FastExcel.createReadableWorkbook(file);
            // workBook.setSSTType(BIFFSetting.SST_TYPE_TEMPFILE);
            // workBook.open();
            // Sheet sheet = workBook.getSheet(0);
            // int i = sheet.getFirstRow();
            // while(i < sheet.getLastRow()){
            // HashMap record = new HashMap();
            // for (int j = sheet.getFirstColumn(); j <sheet.getLastColumn();
            // j++) {
            // String field = (String) mapFields.get(String.valueOf(j+1));
            // String value = sheet.getCell(i, j);
            // if(field!=null && value!=null){
            // record.put(field, value);
            //
            // if((j+1)==unique){
            // uniqueFieldvalue =value;
            // }
            // }
            // }
            //
            // if(record.size()>0){
            // List lst = dynaBeanManager.find("from " + tableName +
            // " t where t." +
            // uniqueFieldName + " = '" + uniqueFieldvalue + "'");
            // if(lst.size()==0){
            // if(!record.containsKey("reportinstance_guid")){
            // record.put("reportinstance_guid", ri.getGuid());
            // }
            // if(!record.containsKey("item_guid")){
            // String guid = new GUID().toString();
            // record.put("item_guid", guid);
            // }
            // dynaBeanManager.saveObject(tableName,
            // HibernateUtil.convertType(tableName, record,
            // SystemConstants.REPORT_DYNAMODEL));
            // count++;
            // }else{
            // HashMap<String,Object> recordOld =
            // (HashMap<String,Object>)lst.get(0);
            // for(String key : recordOld.keySet()){
            // if(record.containsKey(key) && record.get(key)!=null){
            // recordOld.put(key, record.get(key));
            // }
            // }
            //
            // dynaBeanManager.saveObject(tableName,
            // HibernateUtil.convertType(tableName, recordOld,
            // SystemConstants.REPORT_DYNAMODEL));
            // count++;
            // }
            // }
            //
            // i++;
            // }
            // workBook.close();
            // message = "导入成功，总个数:\r\n" + count;
            // }catch(Exception e){
            // e.printStackTrace();
            // message = "导入完成，但有失败条目，成功个数:\r\n" + count + "\r\n" +
            // e.getMessage();
            // }
            // }
            // }
        } else {
            if (templateRangeList != null && !templateRangeList.isEmpty()) {
                this.saveRange(ri, rd, templateGuid, rangeColumnCodeMap, fromImp, needSkip, templateRangeMap, templateRangeList, templateIndicationMap, beforeReportData, afterReportData);
            }
        }

        String tableName = ri.getSo().getTableName().toLowerCase().trim();
        String soInstanceGuid = ri.getSoInstanceGuid();
        String soInstanceCode = "";
        String soInstanceName = "";
        String levelCode = "";
        HashMap<String, Object> dynaBean = (HashMap<String, Object>) dynaBeanManager.getObject(tableName, soInstanceGuid);
        if (dynaBean != null && dynaBean.containsKey("level_code")) {
            levelCode = (String) dynaBean.get("level_code");
            soInstanceCode = (String) dynaBean.get("item_code");
            soInstanceName = (String) dynaBean.get("item_name");
        }

        // 没有强制性审核错误，只有一般性审核错误，则修改reportInstance状态为：审核未通过，否则状态为通过
        ReportInstance reportInstance = (ReportInstance) reportInstanceManager.getObject(ReportInstance.class, ri.getGuid());
        if (containedFaultMap != null && !containedFaultMap.isEmpty()) {
            reportInstance.setStatus(ReportInstance.STATUS_HASNORMALERROR);
        } else {
            reportInstance.setStatus(ReportInstance.STATUS_YES);
        }

        if (clientJsValidationError.equals("true")) {
            reportInstance.setStatus(ReportInstance.STATUS_HASNORMALERROR);
        }

        // 修改更新时间
        // 1：新增 2：修改 3：删除
        int operateType = 2;
        Map<String, String> beforeIndis = beforeReportData.getIndis();
        if (beforeIndis == null) {
            // 表明这是新增
            operateType = 1;
        }
        if (operateType == 1) {
            reportInstance.setFirstUploadDate(new Date());
        }
        reportInstance.setLastModifiedDate(new Date());
        reportInstance.setSoInstanceCode(soInstanceCode);
        reportInstance.setSoInstanceName(soInstanceName);
        reportInstance.setLevelCode((String) levelCode);

        reportInstanceManager.saveObject(reportInstance);
    }

    private void saveIndication(ReportInstance ri, ReportData rd, String templateGuid, List<TemplateIndication> templateIndications, Map<String, TemplateIndication> templateIndicationsMap, boolean fromImp, boolean needSkip, ReportData beforeReportData, ReportData afterReportData) throws Exception {
        Map<String, String> indis = rd.getIndis();
        if (indis == null || indis.isEmpty()) {
            return;
        }

        String reportInstanceGuid = ri.getGuid();

        List<String> tableNames = new ArrayList<String>();
        for (TemplateIndication ti : templateIndications) {
            String tableName = ti.getTableName();
            if (tableName.indexOf("dyna_data_") > -1 && !tableNames.contains(tableName)) {
                tableNames.add(tableName);
            }
        }

        if (tableNames.isEmpty()) {
            throw new Exception("没有对模板定义好数据库字段影射关系");
        }

        Map<String, Map> savedMapOfTables = new HashMap<String, Map>();
        Map<String, Boolean> editOfTables = new HashMap<String, Boolean>();
        for (String tableName : tableNames) {
            Map<String, String> savedMap = new HashMap<String, String>();
            for (TemplateIndication ti : templateIndications) {
                if (tableName.equalsIgnoreCase(ti.getTableName())) {
                    String columnName = ti.getColumnName();
                    String aliasName = ti.getAlias_Name();
                    String aliasValue = indis.get(aliasName);
                    savedMap.put(columnName.toLowerCase(), aliasValue);
                }
            }

            Map loadedMap = (Map) this.getObject(tableName, reportInstanceGuid);
            //{jsbr=null, tbdw=null, tabindex=null, $type$=dyna_data_jsbrd, tbrq=null, tbr=null, reportinstance_guid=AC100142000000000060E0510000016D}
            if (loadedMap == null) {
                // 没有则新增
                savedMap.put("reportinstance_guid", reportInstanceGuid);
                editOfTables.put(tableName, false);
            } else {
                // 还需要从数据库再取一遍，为了保存修改轨迹
                Map beforeMap = this.getIndicationData(reportInstanceGuid, templateIndications);
                //{jsbr=null, tbdw=null, reportinstance_guid=AC100142000000000060E0510000016D, tbrq=null, tbr=null}
                beforeReportData.setIndis(beforeMap);

                loadedMap.remove("$type$");
                Iterator<String> savedMapIterator = savedMap.keySet().iterator();
                while (savedMapIterator.hasNext()) {
                    String columnName = savedMapIterator.next();
                    loadedMap.put(columnName.toLowerCase(), savedMap.get(columnName));
                }
                savedMap = loadedMap;
                editOfTables.put(tableName, true);
            }
            savedMapOfTables.put(tableName, savedMap);
        }

        boolean afterReportDataNeed = true;
        for (String tableName : tableNames) {
            if (!fromImp) {
                this.saveObject(tableName, HibernateUtil.convertType(tableName, savedMapOfTables.get(tableName), SystemConstants.REPORT_DYNAMODEL));
            } else {
                // import
                boolean isEdit = editOfTables.get(tableName);
                if (needSkip) {
                    if (isEdit) {
                        // 有则跳过
                        afterReportDataNeed = false;
                    } else {
                        // 没有则新增
                        this.saveObject(tableName, HibernateUtil.convertType(tableName, savedMapOfTables.get(tableName), SystemConstants.REPORT_DYNAMODEL));
                    }
                } else {
                    if (isEdit) {
                        this.saveObject(tableName, HibernateUtil.convertType(tableName, savedMapOfTables.get(tableName), SystemConstants.REPORT_DYNAMODEL));
                    } else {
                        // 没有则新增
                        this.saveObject(tableName, HibernateUtil.convertType(tableName, savedMapOfTables.get(tableName), SystemConstants.REPORT_DYNAMODEL));
                    }
                }
            }
        }

        // 还需要从数据库再取一遍，为了保存修改轨迹
        if (afterReportDataNeed) {
            Map afterMap = this.getIndicationData(reportInstanceGuid, templateIndications);
            afterReportData.setIndis(afterMap);
        }
    }

    @SuppressWarnings("rawtypes")
    private void saveRange(ReportInstance ri, ReportData rd, String templateGuid, Map<String, Map<String, String>> rangeColumnCodeMap, boolean fromImp, boolean needSkip, Map<String, TemplateRange> templateRangeMap, List<TemplateRange> templateRangeList, Map<String, TemplateIndication> templateIndicationMap, ReportData beforeReportData, ReportData afterReportData) throws Exception {
        Map<String, List<Map<String, String>>> savedMap = new HashMap<String, List<Map<String, String>>>();
        Map<String, RangeObj> ranges = rd.getRanges();
        if (ranges == null)
            return;
        Iterator<String> rangesIt = ranges.keySet().iterator();

        // 还需要先从数据库取一遍，为了保存修改轨迹
        try {
            Map beforeMap = this.getRangeData(ri.getGuid(), templateGuid, templateRangeList, templateIndicationMap, true);
            beforeReportData.setRanges(beforeMap);
        } catch (Exception e) {
            // ignore
        }

        while (rangesIt.hasNext()) {
            String rangeName = rangesIt.next();
            Map<String, String> columnCodeMap = rangeColumnCodeMap.get(rangeName);
            //{3=dyna_dataset_jsbrd_range1###field2, 2=dyna_dataset_jsbrd_range1###field1, 10=dyna_dataset_jsbrd_range1###field6, 1=dyna_dataset_jsbrd_range1###DAIMA, 6=dyna_dataset_jsbrd_range1###field4, 4=dyna_dataset_jsbrd_range1###field3, 8=dyna_dataset_jsbrd_range1###field5, 11=dyna_dataset_jsbrd_range1###field7}、、
            TemplateRange templateRange = templateRangeMap.get(rangeName);
            
            RangeObj range = ranges.get(rangeName);
            Map<String, RowObj> rows = range.getRows();
            Iterator<String> rowIt = rows.keySet().iterator();

            String tableName = null;
            while (rowIt.hasNext()) {
                String rowCatalogCode = rowIt.next();
                RowObj row = rows.get(rowCatalogCode);
                Map<String, String> cols = row.getCols();

                Map<String, String> innerSavedMap = new HashMap<String, String>();
                List<Map<String, String>> savedList = null;
                String columnName = null;

                String reportInstanceGuid = ri.getGuid();

                Iterator<String> colIt = cols.keySet().iterator();
                while (colIt.hasNext()) {
                    String columnCode = colIt.next();
                    String tableColumn = columnCodeMap.get(columnCode);
                    if (tableColumn == null) {
                        innerSavedMap.put(columnCode, cols.get(columnCode));

                        continue;
                    }

                    String[] tableColumnColl = tableColumn.split("###");

                    tableName = tableColumnColl[0].toLowerCase();
                    columnName = tableColumnColl[1].toLowerCase();

                    savedList = savedMap.get(tableName);
                    if (savedList == null) {
                        savedList = new ArrayList<Map<String, String>>();
                        savedMap.put(tableName, savedList);
                    }
                    innerSavedMap.put(columnName, cols.get(columnCode));
                }
                
                String catalogCodeColumnCode = templateRange.getCatalogCodeColumnCode();
                String tableColumn = columnCodeMap.get(catalogCodeColumnCode);
                String[] tableColumnColl = tableColumn.split("###");
                String catalogCodeColumn = tableColumnColl[1].trim().toLowerCase();
                String catalogCode = innerSavedMap.get(catalogCodeColumn);
                String itemGuid = innerSavedMap.get("item_guid");
                
                innerSavedMap.put("tabindex", "100.00");
                innerSavedMap.put("reportinstance_guid", reportInstanceGuid);
                if (!fromImp) {
                    if(itemGuid==null || itemGuid.trim().length()==0){
                        List list = this.find("from " + tableName + " as t where t.reportinstance_guid='" + reportInstanceGuid + "' and t." + catalogCodeColumn + "='" + catalogCode + "'");
                        if (list == null || list.isEmpty()) {
                            // reportinstance_guid和代码列唯一确定一行， 没有则新增
                            innerSavedMap.put("item_guid", new GUID().toString());
                        }else{
                            Map loadedMap = (Map) list.get(list.size()-1);
                            loadedMap.remove("$type$");
                            Iterator<String> innerSavedMapIterator = innerSavedMap.keySet().iterator();
                            while (innerSavedMapIterator.hasNext()) {
                                columnName = innerSavedMapIterator.next();
                                if(!"item_guid".equalsIgnoreCase(columnName)){
                                    loadedMap.put(columnName, innerSavedMap.get(columnName));
                                }
                            }
                            innerSavedMap = loadedMap;
                        }
                    }
                    
                    innerSavedMap = HibernateUtil.convertType(tableName, innerSavedMap, SystemConstants.REPORT_DYNAMODEL);
                    savedList.add(innerSavedMap);
                } else { //数据导入，应该没有item_guid
                    List list = this.find("from " + tableName + " as t where t.reportinstance_guid='" + reportInstanceGuid + "' and t." + catalogCodeColumn + "='" + catalogCode + "'");
                    if (needSkip) {
                        if (list != null && !list.isEmpty()) {
                            // 有则跳过
                        } else {
                            // 没有则新增
                            innerSavedMap.put("item_guid", new GUID().toString());
                            savedList.add(innerSavedMap);
                        }
                    } else {
                        if (list != null && !list.isEmpty()) {
                            // 有则覆盖
                            Map loadedMap = (Map) list.get(list.size()-1);
                            loadedMap.remove("$type$");
                            Iterator<String> innerSavedMapIterator = innerSavedMap.keySet().iterator();
                            while (innerSavedMapIterator.hasNext()) {
                                columnName = innerSavedMapIterator.next();
                                if(!"item_guid".equalsIgnoreCase(columnName)){
                                    loadedMap.put(columnName, innerSavedMap.get(columnName));
                                }
                            }
                            innerSavedMap = loadedMap;

                            savedList.add(innerSavedMap);
                        } else {
                            // 没有则新增
                            innerSavedMap.put("item_guid", new GUID().toString());
                            savedList.add(innerSavedMap);
                        }
                    }
                }
            }

            // 假如是二维增一或者不定长表，则在保存数据前需要删除原先的数据
            if (templateRange.getRangeType() == TemplateRange.RANGETYPE_ERWEIZENGYI || templateRange.getRangeType() == TemplateRange.RANGETYPE_TOPTOBOTTOM) {
                String sql = "from " + tableName + " where reportinstance_guid='" + ri.getGuid() + "'";
                List<Map> originalList = this.find(sql);
                List<Map<String, String>> editedList = savedMap.get(tableName);

                List<Map> tempList = new ArrayList<Map>();
                for (Map originalMap : originalList) {
                    String originalItemGuid = (String) originalMap.get("item_guid");
                    boolean found = false;
                    for (Map<String, String> editedMap : editedList) {
                        String editedItemGuid = editedMap.get("item_guid");
                        if (editedItemGuid != null && originalItemGuid.equals(editedItemGuid)) {
                            found = true;
                        }
                    }
                    if (!found) {
                        tempList.add(originalMap);
                    }
                    found = false;
                }

                for (Map map : tempList) {
                    String originalItemGuid = (String) map.get("item_guid");
                    this.removeObject(tableName, originalItemGuid);
                    originalList.remove(map);
                }

                this.saveObjects(originalList);
            }
        }

        this.saveRangeData(savedMap);

        // 还需要从数据库再取一遍，为了保存修改轨迹
        try {
            Map afterMap = this.getRangeData(ri.getGuid(), templateGuid, templateRangeList, templateIndicationMap, true);
            afterReportData.setRanges(afterMap);
        } catch (Exception e) {
            // ignore
        }
    }

    private void saveRangeData(Map<String, List<Map<String, String>>> savedMap) throws Exception {
        Iterator<String> iterator = savedMap.keySet().iterator();
        while (iterator.hasNext()) {
            String tableName = iterator.next();

            List<Map<String, String>> savedList = savedMap.get(tableName);
            for (int i = 0; i < savedList.size(); i++) {
                Map<String, String> innerMap = savedList.get(i);
                Map<String, String> transformedMap = HibernateUtil.convertType(tableName, innerMap, SystemConstants.REPORT_DYNAMODEL);

                //this.saveObject(tableName, transformedMap);
                this.mergeObject(tableName, transformedMap);
            }
        }
    }

    public ReportData getReportData(ReportInstance ri, String templateGuid) throws Exception {
        Template template = (Template) templateManager.getObject(Template.class, templateGuid);
        List<TemplateIndication> templateIndications = template.getTemplateIndications();
        List<TemplateRange> templateRanges = template.getTemplateRanges();

        Map<String, TemplateIndication> templateIndicationsMap = new HashMap<String, TemplateIndication>();
        for (int i = 0; i < templateIndications.size(); i++) {
            TemplateIndication ti = templateIndications.get(i);
            templateIndicationsMap.put(ti.getAlias_Name(), ti);
        }

        Map<String, TemplateIndication> columnTemplateIndicationMap = new HashMap<String, TemplateIndication>();
        for (int i = 0; i < templateIndications.size(); i++) {
            TemplateIndication ti = templateIndications.get(i);
            String columnName = ti.getColumnName();
            if (columnName != null)
                columnName = columnName.toLowerCase();
            columnTemplateIndicationMap.put(columnName, ti);
        }

        ReportData rd = new ReportData();
        Map<String, String> indis = this.getIndicationData(ri.getGuid(), templateIndications);
        rd.setIndis(indis);

        Map<String, RangeObj> ranges = this.getRangeData(ri.getGuid(), templateGuid, templateRanges, templateIndicationsMap, false);
        rd.setRanges(ranges);

        return rd;
    }

    public ReportData getBaseInfoData(String soInstanceGuid, String tableName, String templateGuid) throws Exception {
        Template template = (Template) templateManager.getObject(Template.class, templateGuid);
        List<TemplateIndication> templateIndications = template.getTemplateIndications();
        List<TemplateRange> templateRanges = template.getTemplateRanges();

        Map<String, TemplateIndication> columnTemplateIndicationMap = new HashMap<String, TemplateIndication>();
        for (int i = 0; i < templateIndications.size(); i++) {
            TemplateIndication ti = templateIndications.get(i);
            String columnName = ti.getColumnName();
            if (columnName != null)
                columnName = columnName.toLowerCase();
            columnTemplateIndicationMap.put(columnName, ti);
        }

        ReportData rd = new ReportData();
        Map<String, String> indis = this.getBaseInfoIndicationData(soInstanceGuid, tableName, columnTemplateIndicationMap);
        rd.setIndis(indis);

        // 无ranges

        return rd;
    }

    // private String doFormat(String value,List<Field> fields) throws Exception
    // {
    // for(int i=0;i<fields.size();i++){
    // Field field = fields.get(i);
    //
    // List<FieldValidator> fieldValidators = field.getFieldValidators();
    // for(int j=0;j<fieldValidators.size();j++){
    // FieldValidator fieldValidator = fieldValidators.get(j);
    // switch(fieldValidator.getType()){
    // case(FieldValidator.TYPE_UNKNOWN):
    // break;
    // case(FieldValidator.TYPE_INT):
    // if(value!=null&&!value.equals("")){
    // try {
    // Double dValue = Double.valueOf(value);
    // Integer iValue = dValue.intValue();
    // return String.valueOf(iValue);
    // } catch (Exception e) {
    // //
    // }
    // }
    //
    // break;
    // case(FieldValidator.TYPE_DOUBLE):
    // if(value!=null&&!value.equals("")){
    // try {
    // Double dValue = Double.valueOf(value);
    // Integer iValue = dValue.intValue();
    // if(dValue>iValue){
    // return value;
    // }else{
    // String strValue = String.valueOf(iValue);
    // return strValue;
    // }
    // } catch (Exception e) {
    //
    // }
    // }
    //
    // break;
    // case(FieldValidator.TYPE_STRING):
    //
    // break;
    // }
    // }
    // }
    //
    // return value;
    // }

    private Map<String, String> getIndicationData(String reportInstanceGuid, List<TemplateIndication> templateIndications) throws Exception {
        Map<String, String> returnedMap = new HashMap<String, String>();
        List<String> tableNames = new ArrayList<String>();

        for (TemplateIndication ti : templateIndications) {
            String tableName = ti.getTableName();
            if (tableName.indexOf("dyna_data_") > -1 && !tableNames.contains(tableName)) {
                tableNames.add(tableName);
            }
        }

        for (String tableName : tableNames) {
            String hqlFields = "";
            List<String> columnNames = new ArrayList<String>();
            HashMap<String, String> column2Alias = new HashMap<String, String>();

            for (TemplateIndication ti : templateIndications) {
                if (tableName.equalsIgnoreCase(ti.getTableName())) {
                    String columnName = ti.getColumnName().trim();
                    columnNames.add(columnName);
                    column2Alias.put(columnName, ti.getAlias_Name());
                    if (hqlFields.length() == 0) {
                        hqlFields = columnName + " as " + columnName;
                    } else {
                        hqlFields += "," + columnName + " as " + columnName;
                    }
                }
            }

            List<HashMap<String, Object>> list = this.find("from " + tableName + " as t where t.reportinstance_guid='" + reportInstanceGuid + "'");
            // List<HashMap<String,Object>> list = this.find("select new map(" +
            // hqlFields + ") from " + tableName +
            // " as t where t.reportinstance_guid='" + reportInstanceGuid +
            // "'");
            if (list.size() > 0) {
                HashMap<String, Object> map = list.get(0);
                for (String columnName : columnNames) {
                    Object columnValue = map.get(columnName.toLowerCase());
                    String value = null;
                    if (columnValue != null) {
                        if ((columnValue instanceof Double) || (columnValue instanceof Float)) {
                            value = String.format("%.2f", columnValue);
                            if (value.endsWith(".00")) {
                                // 表示没有小数点
                                value = value.substring(0, value.length() - 3);
                            }
                        } else {
                            value = columnValue.toString();
                        }
                    }

                    String aliasName = column2Alias.get(columnName);
                    returnedMap.put(aliasName, value);
                }
            }
        }

        returnedMap.put("reportinstance_guid", reportInstanceGuid);
        return returnedMap;
    }

    private Map<String, String> getBaseInfoIndicationData(String soInstanceGuid, String tableName, Map<String, TemplateIndication> columnTemplateIndicationMap) throws Exception {
        List list = this.find("from " + tableName + " as t where t.item_guid='" + soInstanceGuid + "'");

        Map<String, String> returnedMap = new HashMap<String, String>();
        if (list.size() > 0) {
            Map map = (Map) list.get(0);

            Iterator<String> iterator = map.keySet().iterator();
            while (iterator.hasNext()) {
                String columnName = iterator.next();
                TemplateIndication ti = columnTemplateIndicationMap.get(columnName);
                String aliasName = null;
                if (ti != null) {
                    aliasName = ti.getAlias_Name();
                } else {
                    aliasName = columnName;
                }

                Object columnValue = map.get(columnName.toLowerCase());
                String value = null;
                if (columnValue != null) {
                    if ((columnValue instanceof Double) || (columnValue instanceof Float)) {
                        value = String.format("%.2f", columnValue);
                        if (value.endsWith(".00")) {
                            // 表示没有小数点
                            value = value.substring(0, value.length() - 3);
                        }
                    } else {
                        value = columnValue.toString();
                    }
                }

                returnedMap.put(aliasName, value);
            }

            String item_guid = (String) map.get("item_guid");
            returnedMap.put("item_guid", item_guid);
        }

        return returnedMap;
    }

    private Map<String, RangeObj> getRangeData(String reportInstanceGuid, String templateGuid, List<TemplateRange> templateRanges, Map<String, TemplateIndication> templateIndicationsMap, boolean pure) throws Exception {
        Map<String, RangeObj> returnedMap = new HashMap<String, RangeObj>();

        if (templateRanges.isEmpty())
            return returnedMap;

        Map<String, String> tableNameMap = new HashMap<String, String>();

        boolean found = false;

        if (templateRanges.size() > 1) {
            for (int i = 0; i < templateRanges.size(); i++) {
                TemplateRange templateRange = templateRanges.get(i);
                //templateRange包含的代码列的值，对应数据库横表的业务主键，即行定义
                String containedCodes = templateRange.getContainedCodes();
                if (containedCodes != null) {
                    String[] strContainedCodesColl = containedCodes.split(",");
                    List<String> containedCodeList = Arrays.asList(strContainedCodesColl);
                    templateRange.setContainedCodeList(containedCodeList);
                }
            }
        }

        for (int i = 0; i < templateRanges.size(); i++) {
            found = false;

            TemplateRange tr = templateRanges.get(i);
            //templateRange包含的指标列的值，对应数据库横表的其他列,即列定义
            //[daima, field1, field2, field3, field4, field5, field6, field7]
            String containedIndications = tr.getIncludedAlias();
            String[] containedIndicationColl = containedIndications.split(",");
            String tableName = null;
            for (int j = 0; j < containedIndicationColl.length; j++) {
                String containedIndicationName = containedIndicationColl[j];
                TemplateIndication ti = templateIndicationsMap.get(containedIndicationName);
                tableName = ti.getTableName();

                Object o = tableNameMap.get(tableName);
                if (o == null) {
                    tableNameMap.put(tableName, "0");
                    found = true;
                }

                break;
            }

            if (found) {
                // 组建每个range中对应的catalogName
                Map<String, String> rangeCatalogNameMap = this.makeRangeCatalogName(templateGuid);

                String rangeName = tr.getName();
                String catalogName = rangeCatalogNameMap.get(rangeName);
                TemplateIndication tiCatalog = templateIndicationsMap.get(catalogName);
                //数据库列名catalogColumnName=daima
                String catalogColumnName = tiCatalog.getColumnName().toLowerCase();

                List list = new ArrayList();
                if ("CA68830FFFFFFFFFC14F229A000004EE".equals(templateGuid)) { // 附表6-2省级集中招标采购的药品目录清单
                    list = this.find("from " + tableName + " as t where t.reportinstance_guid='" + reportInstanceGuid + "' order by t." + catalogColumnName, 0, 10);
                } else {
                    list = this.find("from " + tableName + " as t where t.reportinstance_guid='" + reportInstanceGuid + "' order by t." + catalogColumnName);
                }
                //同一个物理表tableName可能对应多个同结构的range
                for (int j = 0; j < list.size(); j++) {
                    Map map = (Map) list.get(j);
                    Object catalogCode = map.get(catalogColumnName);//'H001'实际上就是行代码

                    // 模板中内含range 2个以上时，要根据内含的catalogCodes来区分数据是属于哪个range，对应的结果保存在rangeName中
                    if (templateRanges.size() > 1) {
                        for (int k = 0; k < templateRanges.size(); k++) {
                            TemplateRange templateRange = templateRanges.get(k);
                            List<String> containedCodeList = templateRange.getContainedCodeList();
                            if (containedCodeList == null)
                                continue;
                            if (containedCodeList.contains(catalogCode.toString())) {
                                if (templateRange.getName().equals(rangeName))
                                    break;

                                rangeName = templateRange.getName();
                                break;
                            }
                        }
                    }
                    //rd.ranges['range1'].rows['H001'].cols['7']
                    //rangename='range1'
                    //catalogCode='H001'实际上就是行代码
                    //columnCode='7'
                    //rd.indis['shequ']
                    //自由项的别名aliasname='shequ'
                    for (int k = 0; k < containedIndicationColl.length; k++) {
                        String containedIndicationName = containedIndicationColl[k];
                        //containedIndicationName=daima 对应excel某个CELL的别名
                        TemplateIndication ti = templateIndicationsMap.get(containedIndicationName);
                        String columnCode = ti.getAlias_ColumnCode();//columnCode =甲or乙or 丙 excel表上的列代码

                        String realColumnName = ti.getColumnName().toLowerCase();//数据库列名 filed1
                        Object columnValue = map.get(realColumnName);
                        String value = null;
                        if (columnValue == null) {
                            continue;
                            // value = "";
                        } else {
                            if ((columnValue instanceof Double) || (columnValue instanceof Float)) {
                                value = String.format("%.2f", columnValue);
                                if (value.endsWith(".00")) {
                                    // 表示没有小数点
                                    value = value.substring(0, value.length() - 3);
                                }
                            } else {
                                value = columnValue.toString();
                            }
                        }

                        RangeObj range = returnedMap.get(rangeName);
                        if (range == null) {
                            range = new RangeObj();
                            returnedMap.put(rangeName, range);
                        }

                        Map<String, RowObj> rows = range.getRows();
                        if (rows == null) {
                            rows = new HashMap<String, RowObj>();
                            range.setRows(rows);
                        }
                        //行是用catalogCode作为主键，所谓业务主键
                        RowObj row = rows.get(catalogCode.toString());

                        if (row == null) {
                            row = new RowObj();
                            rows.put(catalogCode.toString(), row);
                        }

                        Map<String, String> cols = row.getCols();
                        if (cols == null) {
                            cols = new HashMap<String, String>();
                            row.setCols(cols);
                        }

                        // String rangeRowColumnName = rangeName + "[" +
                        // catalogCode + "," + columnCode + "]";
                        //
                        // if(validator!=null){
                        // List<Field> fields =
                        // validator.getNameToField(rangeRowColumnName, true);
                        // if(fields!=null){
                        // value = this.doFormat(value.toString(), fields);
                        // }
                        // }

                        if (pure) {
                            cols.put(containedIndicationName, value);
                        } else {
                            cols.put(columnCode, value);
                        }
                    }

                    String item_guid = (String) map.get("item_guid");//range对应表中的物理主键
                    returnedMap.get(rangeName).getRows().get(catalogCode.toString()).getCols().put("item_guid", item_guid);
                }
            }
        }

        return returnedMap;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * net.risesoft.risebi.collection.service.DataOperationManager#removeData
     * (java.lang.String, net.risesoft.risebi.collection.model.User)
     */
    @Transactional(rollbackFor = { java.lang.Exception.class })
    public void removeData(String reportInstanceGuid, User user) throws Exception {
        // 根据reportInstanceGuid获得模板
        ReportInstance reportInstance = (ReportInstance) this.getObject(ReportInstance.class, reportInstanceGuid);
        Template template = reportInstance.getTemplate();
        String templateGuid = template.getGuid();

        // 组成修改前的纪录
        ReportData beforeReportData = this.getReportData(reportInstance, templateGuid);
        ReportData afterReportData = new ReportData();

        // 所有数据存储的表
        List<String> tables = templateIndicationManager.getTablesByTemplate(templateGuid);

        // 删除表中的次序，其实这里无关主细表的次序，反正在一个事务内
        for (String tableName : tables) {
            String sql = "delete from " + tableName + " where ReportInstance_Guid='" + reportInstanceGuid + "'";
            this.execute(sql);
        }

        // 修改reportinstance的状态为 未报（0），最后修改时间
        reportInstance.setStatus(ReportInstance.STATUS_NO);
        reportInstance.setLastModifiedDate(new Date());
        reportInstance.setLevelCode("");
        reportInstance.setLevelCodeSubmitted("");
        reportInstance.setLockStatus(0);
        reportInstance.setVerifyStatus(0);
        this.saveObject(reportInstance);

        // 发送新增、修改数据日志（异步事件）
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("targetGuid", reportInstanceGuid);
        dataMap.put("beforeReportData", beforeReportData);
        dataMap.put("afterReportData", afterReportData);
        dataMap.put("user", user);
        dataMap.put("baseInfo", false);
        EventObject dataLogEventObject = new DataLogEventObj(this);
        dataLogEventObject.setDataMap(dataMap);
        ContextUtil.getAc().publishEvent(dataLogEventObject);
    }

    public DataOperationDao getDataOperationDao() {
		return dataOperationDao;
	}

	public TemplateManager getTemplateManager() {
		return templateManager;
	}

	public ReportInstanceManager getReportInstanceManager() {
		return reportInstanceManager;
	}

	public ReportInstanceLevelStatusManager getReportInstanceLevelStatusManager() {
		return reportInstanceLevelStatusManager;
	}

	public ReportInstanceOperationManager getReportInstanceOperationManager() {
		return reportInstanceOperationManager;
	}

	public ReportInstanceFileManager getReportInstanceFileManager() {
		return reportInstanceFileManager;
	}

	public Auditor getAuditor() {
		return auditor;
	}

	public ValidatorManager getValidatorManager() {
		return validatorManager;
	}

	public AuditFaultManager getAuditFaultManager() {
		return auditFaultManager;
	}

	public TemplateIndicationManager getTemplateIndicationManager() {
		return templateIndicationManager;
	}

	public DynaBeanManager getDynaBeanManager() {
		return dynaBeanManager;
	}

	public Map<String, String> makeRangeCatalogName(String templateGuid) throws Exception {
        Map<String, String> rangeCatalogNameMap = new HashMap<String, String>();
        Template template = (Template) templateManager.getObject(Template.class, templateGuid);
        List<TemplateRange> templateRanges = template.getTemplateRanges();
        List<TemplateIndication> templateIndications = template.getTemplateIndications();
        for (int i = 0; i < templateRanges.size(); i++) {
            TemplateRange templateRange = templateRanges.get(i);
            //templateRange包含的别名的值，对应EXCEL某列的名字
            String includedAlias = templateRange.getIncludedAlias();
            String[] includedAliasColl = includedAlias.split(",");
            outer: for (int j = 0; j < includedAliasColl.length; j++) {
                String aliasName = includedAliasColl[j];
                for (int k = 0; k < templateIndications.size(); k++) {
                    TemplateIndication templateIndication = templateIndications.get(k);
                    if (templateIndication.getAlias_Name().equals(aliasName)) {
                    	//如果指标的相关getRelated_Catalog_GUID不是空并且getRelated_Catalog_GUID不是空白字符，表示这个指标Catalog相关
                        if (templateIndication.getRelated_Catalog_GUID() != null && !templateIndication.getRelated_Catalog_GUID().equals("")) {
                        	//建立templateRange和aliasName的对应关系
                            rangeCatalogNameMap.put(templateRange.getName(), aliasName);
                            //range1=daima
                            break outer;
                        }
                    }
                }
            }
        }
        return rangeCatalogNameMap;
    }

    public Map<String, List<String>> makeRangeSortedCotalogCodeMap(Map<String, RangeObj> ranges) throws Exception {
        Map<String, List<String>> rangeSortedCotalogCodeMap = new HashMap<String, List<String>>();
        Iterator<String> rangeIt = ranges.keySet().iterator();
        while (rangeIt.hasNext()) {
            String rangeName = rangeIt.next();
            List<String> sortedCatalogCodeList = new ArrayList<String>();
            RangeObj rangeObj = ranges.get(rangeName);
            if (rangeObj != null) {
                Map<String, RowObj> rows = rangeObj.getRows();
                if (rows != null) {
                    Iterator<String> rowIt = rows.keySet().iterator();
                    while (rowIt.hasNext()) {
                        String catalogCode = rowIt.next();
                        if (catalogCode != null)
                            sortedCatalogCodeList.add(catalogCode);
                    }
                }
            }

            Collections.sort(sortedCatalogCodeList, new CatalogCodeComparator());
            rangeSortedCotalogCodeMap.put(rangeName, sortedCatalogCodeList);
        }
        return rangeSortedCotalogCodeMap;
    }

    class CatalogCodeComparator implements Comparator<String> {
        public int compare(String o1, String o2) {
            int i1 = new Integer(o1);
            int i2 = new Integer(o2);
            return i1 - i2;
        }
    }

    public Map addBaseInfoData(Catalog so, ReportData rd, String templateGuid, User user) throws Exception {
        // 建立map提高速度
        Template t = (Template) templateManager.getObject(Template.class, templateGuid);
        List<TemplateIndication> templateIndicationList = t.getTemplateIndications();

        Map<String, TemplateIndication> templateIndicationMap = new HashMap<String, TemplateIndication>();
        for (int i = 0; i < templateIndicationList.size(); i++) {
            TemplateIndication ti = templateIndicationList.get(i);
            templateIndicationMap.put(ti.getAlias_Name(), ti);
        }

        return this.addBaseInfoData(so, rd, templateGuid, templateIndicationList, templateIndicationMap, user, true, true, true, false, false);
    }

    public Map addBaseInfoData(Catalog so, ReportData rd, String templateGuid, List<TemplateIndication> templateIndicationList, Map<String, TemplateIndication> templateIndicationMap, User user, boolean needValidate, boolean needAudit, boolean needSendMessage, boolean fromImp, boolean needSkip) throws Exception {
        Map returnedMap = new HashMap();

        List<Fault> containedFaults = null;
        // 根据 validation.xml 验证数据格式是否正确
        if (needValidate) {
            containedFaults = this.validatorManager.validate(0, templateGuid, rd);
            if (!containedFaults.isEmpty()) {
                returnedMap.put("containedFaults", containedFaults);
                returnedMap.put("validate", "0");
                return returnedMap;
            }
        }

        Map<String, List<Fault>> containedFaultMap = null;
        // 业务审核
        if (needAudit) {
            boolean hasQiangzhixingFault = false;
            containedFaultMap = auditor.doAudit(templateGuid, null, rd, user);
            Iterator<String> it = containedFaultMap.keySet().iterator();
            while (it.hasNext()) {
                String key = it.next();
                String[] keyColl = key.split("###");
                if (keyColl[1].equals("1")) {
                    hasQiangzhixingFault = true;
                    break;
                }
            }

            if (hasQiangzhixingFault) {
                containedFaults = new ArrayList<Fault>();
                Iterator<Entry<String, List<Fault>>> entryIt = containedFaultMap.entrySet().iterator();
                while (entryIt.hasNext()) {
                    List<Fault> faultList = entryIt.next().getValue();
                    containedFaults.addAll(faultList);
                }
                returnedMap.put("containedFaults", containedFaults);
                returnedMap.put("audit", "0");
                return returnedMap;
            }
        }

        ReportData beforeReportData = new ReportData();
        ReportData afterReportData = new ReportData();

        // 保存
        String soInstanceGuid = this.saveBaseInfoData(so, rd, templateGuid, containedFaultMap, templateIndicationList, templateIndicationMap, user, fromImp, needSkip, beforeReportData, afterReportData);

        if (soInstanceGuid == null)
            throw new Exception("尚未定制好填报表单，请联系管理员。");

        // 没有强制性审核错误，只有一般性审核错误，则保存非强制性审核错误
        if (needSendMessage) {
            if (!containedFaultMap.isEmpty()) {
                containedFaults = new ArrayList<Fault>();

                for (Map.Entry<String, List<Fault>> entry : containedFaultMap.entrySet()) {
                    String key = entry.getKey();
                    String[] keyColl = key.split("###");
                    if (keyColl[1].equals("1"))
                        continue;

                    List<Fault> faultList = entry.getValue();
                    containedFaults.addAll(faultList);
                }

                auditFaultManager.saveAuditFault(soInstanceGuid, containedFaults);
            }
        }

        // 发送新增数据日志（异步事件）
        Map<String, Object> dataMap = new HashMap<String, Object>();
        dataMap.put("targetGuid", soInstanceGuid);
        dataMap.put("beforeReportData", beforeReportData);
        dataMap.put("afterReportData", afterReportData);
        dataMap.put("user", user);
        dataMap.put("baseInfo", true);
        dataMap.put("so", so);
        EventObject dataLogEventObject = new DataLogEventObj(this);
        dataLogEventObject.setDataMap(dataMap);
        ContextUtil.getAc().publishEvent(dataLogEventObject);

        returnedMap.put("returnString", BaseAction.ADD);
        returnedMap.put("soi_guid", soInstanceGuid);
        return returnedMap;
    }

    @Transactional(rollbackFor = { java.lang.Exception.class })
    private String saveBaseInfoData(Catalog so, ReportData rd, String templateGuid, Map<String, List<Fault>> containedFaultMap, List<TemplateIndication> templateIndicationList, Map<String, TemplateIndication> templateIndicationMap, User user, boolean fromImp, boolean needSkip, ReportData beforReportData, ReportData afterReportData) throws Exception {
        // 保存游离项
        String soInstanceGuid = this.saveBaseInfoIndication(so, rd, templateGuid, templateIndicationList, templateIndicationMap, fromImp, needSkip, beforReportData, afterReportData);

        // 没有强制性审核错误，只有一般性审核错误，则修改reportInstance状态为：审核未通过，否则状态为通过
        // ReportInstance reportInstance = (ReportInstance)
        // reportInstanceManager.getObject(ReportInstance.class, ri.getGuid());
        // if(containedFaultMap!=null&&!containedFaultMap.isEmpty()){
        // reportInstance.setStatus(ReportInstance.STATUS_HASNORMALERROR);
        // }else{
        // reportInstance.setStatus(ReportInstance.STATUS_YES);
        // }
        // reportInstanceManager.saveObject(reportInstance);

        return soInstanceGuid;
    }

    private String saveBaseInfoIndication(Catalog so, ReportData rd, String templateGuid, List<TemplateIndication> templateIndications, Map<String, TemplateIndication> templateIndicationsMap, boolean fromImp, boolean needSkip, ReportData beforeReportData, ReportData afterReportData) throws Exception {
        String tableName = null;
        for (int i = 0; i < templateIndications.size(); i++) {
            TemplateIndication ti = templateIndications.get(i);
            String tableNameTemp = ti.getTableName();
            if (tableNameTemp.indexOf("dyna_dataset") > -1)
                continue;

            tableName = tableNameTemp;
            break;
        }

        if (tableName == null) {
            throw new Exception("没有对模板定义好数据库字段影射关系");
        }

        Map<String, String> savedMap = new HashMap<String, String>();
        Map<String, String> indis = rd.getIndis();

        if (indis == null || indis.isEmpty())
            return null;

        Iterator<String> indicationIterator = indis.keySet().iterator();
        while (indicationIterator.hasNext()) {
            String aliasName = indicationIterator.next();
            TemplateIndication ti = templateIndicationsMap.get(aliasName);
            if (ti == null) {
                continue;
            }
            String indicationName = ti.getColumnName();
            String indicationValue = indis.get(aliasName);

            if (indicationName != null && !indicationName.equals(""))
                savedMap.put(indicationName.toLowerCase(), indicationValue);
        }

        String soInstanceGuid = indis.get("item_guid");
        if (soInstanceGuid == null) {
            soInstanceGuid = new GUID().toString();
            savedMap.put("catalog_guid", so.getGuid());
            savedMap.put("item_guid", soInstanceGuid);
        } else {
            // 还需要从数据库再取一遍，为了保存修改轨迹
            Map beforeMap = this.getBaseInfoIndicationData(soInstanceGuid, tableName, templateIndicationsMap);
            beforeReportData.setIndis(beforeMap);

            Map loadedMap = (Map) this.getObject(tableName, soInstanceGuid);
            loadedMap.remove("$type$");
            Iterator<String> savedMapIterator = savedMap.keySet().iterator();
            while (savedMapIterator.hasNext()) {
                String columnName = savedMapIterator.next();

                loadedMap.put(columnName.toLowerCase(), savedMap.get(columnName));
            }
            savedMap = loadedMap;
        }

        this.saveObject(tableName, HibernateUtil.convertType(tableName, savedMap, SystemConstants.REPORT_DYNAMODEL));

        // 还需要从数据库再取一遍，为了保存修改轨迹
        Map afterMap = this.getBaseInfoIndicationData(soInstanceGuid, tableName, templateIndicationsMap);
        afterReportData.setIndis(afterMap);

        return soInstanceGuid;
    }
}
